#include "ohos_media_stream.h"
#include <algorithm>
#include "ohos_audio_track.h"
#include "ohos_video_track.h"

namespace ohoswebrtc {

OHOSMediaStream::OHOSMediaStream(
    rtc::scoped_refptr<webrtc::MediaStreamInterface> media_stream, rtc::scoped_refptr<OHOSPeerConnectionFactoryInterface> peer_connection_factory)
    : media_stream_(media_stream),
      peer_connection_factory_(peer_connection_factory),
      signaling_thread_(peer_connection_factory->signaling_thread()) {

  for (auto track : media_stream->GetAudioTracks()) {
    rtc::scoped_refptr<OHOSAudioTrack> audio_track = rtc::scoped_refptr<OHOSAudioTrack>(
        new rtc::RefCountedObject<OHOSAudioTrack>(track, peer_connection_factory));
    rtc::scoped_refptr<OHOSAudioTrackInterface> interface_track = audio_track;
    
    audio_tracks_.push_back(interface_track);
  }

  for (auto track : media_stream->GetVideoTracks()) {
    rtc::scoped_refptr<OHOSVideoTrack> video_track = rtc::scoped_refptr<OHOSVideoTrack>(
        new rtc::RefCountedObject<OHOSVideoTrack>(track, peer_connection_factory));
    rtc::scoped_refptr<OHOSVideoTrackInterface> interface_track = video_track;
    video_tracks_.push_back(interface_track);
  }
  
  stream_id_ = media_stream_->id();
}

OHOSMediaStream::~OHOSMediaStream() {
  RTC_LOG(LS_INFO) << __FUNCTION__ << ": Dtor";
  audio_tracks_.clear();
  video_tracks_.clear();
}

void OHOSMediaStream::AddAudioTrack(rtc::scoped_refptr<OHOSAudioTrackInterface> track) {
  if (signaling_thread_ != nullptr && !signaling_thread_->rtc::Thread::IsCurrent()) {
      signaling_thread_->BlockingCall([&, this]() { this->AddAudioTrack(track); });
      return;
  }

  OHOSAudioTrack* ohos_track = static_cast<OHOSAudioTrack*>(track.get());
  rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> media_track = ohos_track->track();
  // webrtc::MediaStreamTrackInterface* raw_track = media_track.get();
  webrtc::AudioTrackInterface* audio_raw_track =  static_cast<webrtc::AudioTrackInterface*>(media_track.get());
  rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(audio_raw_track);
  if (media_stream_->AddTrack(audio_track)) {
    audio_tracks_.push_back(track);
  }
}

void OHOSMediaStream::AddVideoTrack(rtc::scoped_refptr<OHOSVideoTrackInterface> track) {
  if (signaling_thread_ != nullptr && !signaling_thread_->rtc::Thread::IsCurrent()) {
      signaling_thread_->BlockingCall([&, this]() { this->AddVideoTrack(track); });
      return;
  }
  
  OHOSVideoTrack *ohos_track = static_cast<OHOSVideoTrack*>(track.get());
  rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> media_track = ohos_track->track();
  // webrtc::MediaStreamTrackInterface* raw_track = media_track.get();
  // 使用 static_cast 把原始指针转换为 AudioTrackInterface*
  webrtc::VideoTrackInterface* video_raw_track =  static_cast<webrtc::VideoTrackInterface*>(media_track.get());
// 创建 rtc::scoped_refptr<webrtc::AudioTrackInterface>
  rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(video_raw_track);
  if (media_stream_->AddTrack(video_track)) {
    video_tracks_.push_back(track);
  }
}

void OHOSMediaStream::RemoveAudioTrack(rtc::scoped_refptr<OHOSAudioTrackInterface> track) {
  if (signaling_thread_ != nullptr && !signaling_thread_->rtc::Thread::IsCurrent()) {
      signaling_thread_->BlockingCall([&, this]() { this->RemoveAudioTrack(track); });
      return;
  }

  OHOSAudioTrack* ohos_track = static_cast<OHOSAudioTrack*>(track.get());
  rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> media_track = ohos_track->track();
  // webrtc::MediaStreamTrackInterface* raw_track = media_track.get();
  // 使用 static_cast 把原始指针转换为 AudioTrackInterface*
  webrtc::AudioTrackInterface* audio_raw_track =  static_cast<webrtc::AudioTrackInterface*>(media_track.get());
// 创建 rtc::scoped_refptr<webrtc::AudioTrackInterface>
  rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(audio_raw_track);
  if (media_stream_->RemoveTrack(audio_track)) {
    auto it = std::find(audio_tracks_.begin(), audio_tracks_.end(), track);
    if (it != audio_tracks_.end()) audio_tracks_.erase(it);
    return;
  }
  return;
}

void OHOSMediaStream::RemoveVideoTrack(rtc::scoped_refptr<OHOSVideoTrackInterface> track) {
  if (signaling_thread_ != nullptr && !signaling_thread_->rtc::Thread::IsCurrent()) {
      signaling_thread_->BlockingCall([&, this]() { this->RemoveVideoTrack(track); });
      return;
  }

  OHOSVideoTrack *ohos_track = static_cast<OHOSVideoTrack*>(track.get());
  rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> media_track = ohos_track->track();
  // webrtc::MediaStreamTrackInterface* raw_track = media_track.get();
  // 使用 static_cast 把原始指针转换为 AudioTrackInterface*
  webrtc::VideoTrackInterface* video_raw_track =  static_cast<webrtc::VideoTrackInterface*>(media_track.get());
// 创建 rtc::scoped_refptr<webrtc::AudioTrackInterface>
  rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(video_raw_track);
  if (media_stream_->RemoveTrack(video_track)) {
    auto it = std::find(video_tracks_.begin(), video_tracks_.end(), track);
    if (it != video_tracks_.end()) video_tracks_.erase(it);
    return;
  }
  return;
}

OHOSAudioTrackVector OHOSMediaStream::GetAudioTracks() {
  if (signaling_thread_ != nullptr && !signaling_thread_->rtc::Thread::IsCurrent()) {
     return signaling_thread_->BlockingCall([&, this]() { 
        return this->GetAudioTracks(); 
      });
  }
  return audio_tracks_;
}

OHOSVideoTrackVector OHOSMediaStream::GetVideoTracks() {
  if (signaling_thread_ != nullptr && !signaling_thread_->rtc::Thread::IsCurrent()) {
      return signaling_thread_->BlockingCall([&, this]() { return this->GetVideoTracks(); });
  }
  return video_tracks_;
}

rtc::scoped_refptr<OHOSAudioTrackInterface> OHOSMediaStream::FindAudioTrack(
    const std::string track_id) {
  if (signaling_thread_ != nullptr && !signaling_thread_->rtc::Thread::IsCurrent()) {
    return signaling_thread_->BlockingCall([&, this]() { return this->FindAudioTrack(track_id); });
  }

  for (auto track : audio_tracks_) {
    if (track->id() == track_id) {
      return track;
    }
  }
  return rtc::scoped_refptr<OHOSAudioTrackInterface>();
}

rtc::scoped_refptr<OHOSVideoTrackInterface> OHOSMediaStream::FindVideoTrack(
    const std::string track_id) {
  if (signaling_thread_ != nullptr && !signaling_thread_->rtc::Thread::IsCurrent()) {
      return signaling_thread_->BlockingCall([&, this]() { return this->FindVideoTrack(track_id); });
  }
  for (auto track : video_tracks_) {
    if (track->id() == track_id) {
      return track;
    }
  }
  return rtc::scoped_refptr<OHOSVideoTrackInterface>();
}

} 
